package com.example.my_self_view

import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Rect
import android.graphics.RectF
import android.util.AttributeSet
import android.util.TypedValue
import android.view.View

class QQStepView: View {

    private val outerPaint by lazy { Paint() }
    private val innerPaint by lazy { Paint() }
    private val textPaint by lazy { Paint() }
    private val rect by lazy { Rect() }
    private val rectF by lazy { RectF() }

    private var stepMax = 100
    private var currentStep = 60

    private var outerColor: Int = Color.parseColor("#3F51B5")
    private var innerColor: Int = Color.parseColor("#FF4081")
    private var textColor: Int = Color.parseColor("#FF4081")
    private var arcWidth: Int = 6
    private var textSize: Int = 16

    constructor(context: Context): this(context, null) {
    }

    constructor(context: Context, attrs: AttributeSet?): this(context, attrs, 0) {
    }

    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int): this(context, attrs, defStyleAttr, 0){
    }

    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int): super(context, attrs, defStyleAttr, defStyleRes) {
        initData(attrs)
    }

    private fun initData(attrs: AttributeSet?) {
        val typedArray = context.obtainStyledAttributes(attrs, R.styleable.QQStepView)
        typedArray.apply {
            try {
                outerColor = typedArray.getColor(
                    R.styleable.QQStepView_outerColor,
                    outerColor
                )
                innerColor = typedArray.getColor(
                    R.styleable.QQStepView_innerColor,
                    innerColor
                )
                textColor = typedArray.getColor(
                    R.styleable.QQStepView_stepTextColor,
                    textColor
                )
                arcWidth = typedArray.getDimension(
                    R.styleable.QQStepView_arcWidth,
                    arcWidth.toFloat()
                ).toInt()
                textSize = typedArray.getDimensionPixelSize(
                    R.styleable.QQStepView_stepTextSize,
                    value2px(textSize, TypedValue.COMPLEX_UNIT_SP)
                )
            } finally {
                recycle()
            }
        }

        outerPaint.apply {
            isAntiAlias = true
            this.textSize = this@QQStepView.textSize.toFloat()
            strokeWidth = arcWidth.toFloat()
            color = outerColor
            strokeCap = Paint.Cap.ROUND
            style = Paint.Style.STROKE
        }

        innerPaint.apply {
            isAntiAlias = true
            this.textSize = this@QQStepView.textSize.toFloat()
            strokeWidth = arcWidth.toFloat()
            color = innerColor
            strokeCap = Paint.Cap.ROUND
            style = Paint.Style.STROKE
        }

        textPaint.apply {
            isAntiAlias = true
            this.textSize = this@QQStepView.textSize.toFloat()
            color = textColor
        }
    }

    private fun value2px(value: Int, typedValue: Int): Int {
        return TypedValue.applyDimension(typedValue, value.toFloat(), resources.displayMetrics).toInt()
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        // 调用者在布局文件中可能 wrap_content
        // 获取模式 AT_MOST  40dp

        // 宽度高度不一致时，去最小的一方，确保是个正方形
        var width = MeasureSpec.getSize(widthMeasureSpec)
        var height = MeasureSpec.getSize(heightMeasureSpec)

        if (width > height) width = height
        else height = width

        setMeasuredDimension(width, height)
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        // 6.1 画外圆弧
        val center = width / 2
        val radius = width / 2 - arcWidth / 2
        rectF.apply {
            top = center.toFloat() - radius.toFloat()
            bottom = center.toFloat() + radius.toFloat()
            left = center.toFloat() - radius.toFloat()
            right = center.toFloat() + radius.toFloat()
        }
        canvas.drawArc(rectF, 135f, 270f, false, outerPaint)

        // 6.2 画内圆弧
        if (stepMax == 0) return
        val sweepAngle = currentStep.toFloat() / stepMax.toFloat()
        canvas.drawArc(rectF, 135f, sweepAngle * 270, false, innerPaint)

        // 6.3 画文字
        val stepText = currentStep.toString()
        textPaint.getTextBounds(stepText, 0, stepText.length, rect)
        val dx = width / 2 - rect.width() / 2
        // 基线
        val fontMetricsInt = textPaint.fontMetricsInt
        val dy = - (fontMetricsInt.top + fontMetricsInt.bottom) / 2
        val baseLine = height / 2 + dy
        canvas.drawText(stepText, dx.toFloat(), baseLine.toFloat(), textPaint)
    }

    fun setStepMax(max: Int) {
        synchronized(QQStepView::class) {
            this.stepMax = max
        }
    }

    fun setCurrentStep(currentStep: Int) {
        synchronized(QQStepView::class) {
            this.currentStep = currentStep
            invalidate()
        }
    }
}